use crate::parser::{Token, TokenStream, Parser};
use crate::cobol::{self, Record, RecordLike};
use crate::{Result};

#[derive(Debug)]
pub struct Group {
    level: u32,
    name: String,
    length: u32,
    offset: u32,
    records: Vec<Record>,
}

impl Group {
    pub fn get_records(&self) -> &Vec<Record> {
        &self.records
    }
    pub fn _add_record(&mut self, record: Record){
        self.records.push(record);
    }
}

impl RecordLike for Group {
    fn level(&self) -> u32 {
        self.level
    }
    fn length(&self) -> u32 {
        self.length
    }
    fn name(&self) -> &str {
        &self.name
    }
    fn offset(&self) -> u32 {
        self.offset
    }
}

impl Parser for Group {
    fn parse(stream: &mut TokenStream, offset: u32) -> Result<Self> {
        let level = stream.parse_unsigned()?;
        let name = if stream.may_be(Token::Filler) {
            cobol::normalize_name("FILLER", stream)
        } else {
            cobol::normalize_name(&stream.parse_ident()?, stream)
        };
        let mut offset = if stream.may_be(Token::Redefines){
            let redefined_field = cobol::normalize_name(&stream.parse_ident()?, stream);
            if let Some(redefined_offset) = stream.get_redefine(redefined_field) {
                redefined_offset
            } else {
                offset
            }
        } else {
            offset
        };
        let mut length = 0;
        stream.must_be(Token::Dot)?;
        let mut records = Vec::new();
        loop { 
            let checkpoint = stream.checkpoint();
            if let Ok(record) = Record::parse(stream, offset) {
                 if record.level() <= level {
                     stream.rollback(checkpoint);
                     return Ok(Group { level, name, length, offset, records })
                } else {
                     length += record.length();
                     offset += record.length();
                     records.push(record);
                }
            } else {
                return Ok(Group { level, name, length, offset, records })
            }
        }
    }
}
 

